﻿
Imports System.Net.Sockets
Imports System.Runtime.CompilerServices
Imports osi.root.constants
Imports osi.root.connector
Imports osi.root.envs

Public Module _socket
    Private Function poll(ByVal s As Socket, ByVal timeout_ms As Int64, ByVal mode As SelectMode) As Boolean
        If s Is Nothing Then
            Return False
        Else
            Try
                Return s.Poll(milliseconds_to_microseconds(timeout_ms),
                              mode)
            Catch ex As Exception
                If network_trace Then
                    raise_error(error_type.warning,
                                "failed to poll ",
                                If(mode = SelectMode.SelectError,
                                   "error",
                                   If(mode = SelectMode.SelectRead,
                                      "read",
                                      "write")),
                                " status of the socket, ex ",
                                ex.Message())
                End If
                Return False
            End Try
        End If
    End Function

    <Extension()> Public Function poll_write(ByVal s As Socket, Optional ByVal timeout_ms As Int64 = 0) As Boolean
        Return poll(s, timeout_ms, SelectMode.SelectWrite)
    End Function

    <Extension()> Public Function poll_read(ByVal s As Socket, Optional ByVal timeout_ms As Int64 = 0) As Boolean
        Return poll(s, timeout_ms, SelectMode.SelectRead)
    End Function

    <Extension()> Public Function poll_error(ByVal s As Socket, Optional ByVal timeout_ms As Int64 = 0) As Boolean
        Return poll(s, timeout_ms, SelectMode.SelectError)
    End Function

    '=0 no data to read
    '<0 client is not connected
    '>0 has data to read
    <Extension()> Public Function buffered_bytes(ByVal s As Socket) As Int32
        If s Is Nothing Then
            Return npos
        Else
            Try
                Return s.Available()
            Catch
                Return npos
            End Try
        End If
    End Function

    <Extension()> Public Function send_buff_size(ByVal s As Socket) As Int32
        If s Is Nothing Then
            Return failure_send_buff_size
        Else
            Try
                Return s.SendBufferSize()
            Catch ex As Exception
                If network_trace Then
                    raise_error(error_type.warning,
                                "failed to get socket send buffer size, ex ",
                                ex.Message())
                End If
                Return failure_send_buff_size
            End Try
        End If
    End Function

    <Extension()> Public Function receive_buff_size(ByVal s As Socket) As Int32
        If s Is Nothing Then
            Return failure_receive_buff_size
        Else
            Try
                Return s.ReceiveBufferSize()
            Catch ex As Exception
                If network_trace Then
                    raise_error(error_type.warning,
                                "failed to get socket receive buffer size, ex ",
                                ex.Message())
                End If
                Return failure_receive_buff_size
            End Try
        End If
    End Function

    <Extension()> Public Function no_delay(ByVal s As Socket) As Boolean
        If s Is Nothing Then
            Return False
        Else
            Try
                Return s.NoDelay()
            Catch ex As Exception
                If network_trace Then
                    raise_error(error_type.warning,
                                "failed to get no-delay setting of socket, ex ",
                                ex.Message())
                End If
                Return False
            End Try
        End If
    End Function

    <Extension()> Public Function set_no_delay(ByVal s As Socket, ByVal v As Boolean) As Boolean
        If s Is Nothing Then
            Return False
        Else
            Try
                s.NoDelay() = v
                Return True
            Catch ex As Exception
                If network_trace Then
                    raise_error(error_type.warning,
                                "failed to set no-delay setting of socket, ex ",
                                ex.Message())
                End If
                Return False
            End Try
        End If
    End Function
End Module
